/*
 * Copyright (c)  2008 Sebastien Tremblay
 *
 * id3-tag-builder - helpers.CheckTreeManager.java
 *
 * All source and documentation is copyrighted by Sebastien Tremblay
 * (seb at ryders dot net) and made available under the Apache License 2.0.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * $Id: CheckTreeManager.java 31 2010-01-14 11:50:23Z ryders $
 */
package com.empireone.id3tagbuilder.gui.tree;

import com.empireone.id3tagbuilder.classes.Path;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Vector;
import javax.swing.JCheckBox;
import javax.swing.JTree;
import javax.swing.tree.TreePath;

/**
 *
 * @author Sebastien Tremblay
 */
public class CheckTreeManager implements MouseListener, KeyListener {

    private CheckTreeSelectionModel selectionModel;
    private JTree tree = new JTree();
    int hotspot = new JCheckBox().getPreferredSize().width;

    /**
     *
     * @param tree
     */
    public CheckTreeManager(JTree tree) {
	this.tree = tree;
	selectionModel = new CheckTreeSelectionModel(tree.getModel());
	tree.setCellRenderer(new CheckTreeCellRenderer(tree.getCellRenderer(), selectionModel));
	tree.addMouseListener(this);
	tree.addKeyListener(this);
    }

    /**
     *
     * @param e
     */
    @Override
    public void mouseClicked(MouseEvent e) {
	TreePath path = tree.getPathForLocation(e.getX(), e.getY());

	if (path == null) {
	    return;
	}
	if (e.getX() > tree.getPathBounds(path).x + hotspot) {
	    return;
	}

	changeSelection(path);
    }

    private void changeSelection(TreePath path) {
	boolean selected = selectionModel.isPathSelected(path, true);

	if (selected) {
	    selectionModel.removeSelectionPath(path);
	} else {
	    selectionModel.addSelectionPath(path);
	}
	tree.treeDidChange();

    }

    /**
     *
     * @return
     */
    public CheckTreeSelectionModel getSelectionModel() {
	return selectionModel;
    }

    /**
     *
     * @param e
     */
    @Override
    public void mousePressed(MouseEvent e) {
	//throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     *
     * @param e
     */
    @Override
    public void mouseReleased(MouseEvent e) {
	//throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     *
     * @param e
     */
    @Override
    public void mouseEntered(MouseEvent e) {
	//throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     *
     * @param e
     */
    @Override
    public void mouseExited(MouseEvent e) {
	//throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     *
     * @param e
     */
    @Override
    public void keyTyped(KeyEvent e) {

	if (e.getKeyChar() == ' ' && e.getModifiersEx() == 0) {
	    for (TreePath path : tree.getSelectionPaths()) {
		changeSelection(path);
	    }
	}

    }

    /**
     *
     * @param e
     */
    @Override
    public void keyPressed(KeyEvent e) {
	//throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     *
     * @param e
     */
    @Override
    public void keyReleased(KeyEvent e) {
	//throw new UnsupportedOperationException("Not supported yet.");
    }

    public void selectNone() {
        TreePath[] paths = this.selectionModel.getSelectionPaths();
        if (paths != null) {
            this.selectionModel.removeSelectionPaths(paths);
            tree.treeDidChange();
        }
    }

    public void selectToggle() {
        /*TreePath[] paths = this.selectionModel.getSelectionPaths();

        boolean changes = false;

        for (TreePath path : selectionModel.getSelectionPaths()) {
        changes = true;
        boolean selected = false;
        for (TreePath sel : paths) {
        if (sel == path) {
        selected = true;
        break;
        }
        }
        if (selected) {
        this.selectionModel.removeSelectionPath(path);
        } else {
        this.selectionModel.addSelectionPath(path);
        }
        }
        if (changes) {
        tree.treeDidChange();
        }*/
    }

    public Vector<Path> getSelectedPaths() {
        Vector<Path> paths = new Vector<Path>();
        for (TreePath tpath : selectionModel.getSelectionPaths()) {

            // The generated tree structure goes like this;
            // [ ] TopNode          <- generated by the code
            //   [ ] RootNode       <- based on the settings.xml config
            //   [ ] RootNode
            //     [ ] FSNode       <- depends on the file system
            //     [ ] FSNode
            //     [ ] FSNode

            // so for each of the selected treepath, we have to ;
            // - extract the Path object out of it
            // - if it's a RootNode, get all its children paths
            // - if it's a TopNode, get all the RootNode's children paths

            // the end result is a list of mp3 folders or mp3 files to be processed

            Path path = (Path) tpath.getLastPathComponent();
            if (path.getRoot() == null) { // this is the TopNode
                for(Path p : path.getChildren()) {
                    paths.addAll(p.getChildren());
                }
            } else if (path.getChildCount() > 0) { // this is a RootNode
                paths.addAll(path.getChildren());
            } else { // this is just a node, folder or file.
                paths.add(path);
            }
        }

        return paths;
    }
}
